/**
* All Rights Reserved , Copyright (C) 2020 , 青岛鼎信通讯股份有限公司
*
* MeetPeroidTaskService
* 会议周期任务
*
* 修改纪录
* 2020-11-04 版本：1.0 donghang 创建。
* @version 版本：1.0
* @author 作者：donghang
* 创建日期：2020-11-04
*/
package com.topscomm.meet.service.impl;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.topscomm.base.calendar.PeroidParams;
import com.topscomm.base.calendar.PeroidRepeatService;
import com.topscomm.base.pojo.BasePermissionManageEntity;
import com.topscomm.base.pojo.BaseRemindConfigEntity;
import com.topscomm.base.service.IBasePermissionManageService;
import com.topscomm.base.service.IBaseRemindConfigService;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.meet.MeetSystemConst.MeetPersonTypeEnum;
import com.topscomm.meet.MeetSystemConst.MeetStateEnum;
import com.topscomm.meet.pojo.MeetManageEntity;
import com.topscomm.meet.pojo.MeetPeroidTaskEntity;
import com.topscomm.meet.pojo.MeetTypeManageEntity;
import com.topscomm.meet.service.IMeetManageService;
import com.topscomm.meet.service.IMeetPeroidTaskService;
import com.topscomm.meet.service.IMeetTypeManageService;
import com.topscomm.meet.service.impl.auto.MeetPeroidTaskServiceAuto;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.DateUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.SessionUserBean;

import cn.hutool.core.date.DateBetween;
import cn.hutool.core.date.DateUnit;

@Service(value = "meetPeroidTaskService")
@Scope(value = "singleton")
public class MeetPeroidTaskService extends MeetPeroidTaskServiceAuto implements IMeetPeroidTaskService {
	@Autowired
	private IBasePermissionManageService basePermissionManageService;
	@Autowired
	private IBaseRemindConfigService baseRemindConfigService;
	@Autowired
	private IMeetManageService meetManageService;
	@Autowired
	private PeroidRepeatService peroidRepeatService;
	@Autowired
	private IMeetTypeManageService meetTypeManageService;

	/**
	 * 保存周期会议数据
	 *
	 * @description:
	 * @param dataMap
	 * @param sessionUserBean
	 * @author: donghang
	 * @date: 2020年11月3日下午12:53:33
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public MeetPeroidTaskEntity save(Map<String, Object> dataMap, SessionUserBean sessionUserBean) {
		// 基础信息
		MeetPeroidTaskEntity meetPeroidEntity = new MeetPeroidTaskEntity();
		meetPeroidEntity = (MeetPeroidTaskEntity) meetPeroidEntity.convertFromMap(dataMap);
		if (ConvertUtil.convertToLong(dataMap.get(meetPeroidEntity.FieldId)) == 0) {
			meetPeroidEntity.setUsercode(sessionUserBean.getUser().getCode());
			meetPeroidEntity.setUsername(sessionUserBean.getUser().getName());
			meetPeroidEntity = this.insert(meetPeroidEntity);
		} else {
			this.updateEntity(meetPeroidEntity);
		}
		// 参会人员信息
		Map<String, Object> selectUsers = (Map<String, Object>) dataMap.get("selectUsers");
		List<BasePermissionManageEntity> userList = this.basePermissionManageService.processSelectUsers(selectUsers,
				MeetPersonTypeEnum.Attend, sessionUserBean.getUser().getCode(), sessionUserBean.getUser().getName());
		if (userList != null)
			basePermissionManageService.batchSaveList(String.valueOf(meetPeroidEntity.getId()),
					MeetPeroidTaskEntity.tableName, userList);
		// 提醒配置信息
		List<Map<String, Object>> remindList = null;
		if (dataMap.containsKey("remindList"))
			remindList = (List<Map<String, Object>>) dataMap.get("remindList");
		if (remindList != null)
			this.baseRemindConfigService.batchSaveRemindConfigList(String.valueOf(meetPeroidEntity.getId()),
					MeetPeroidTaskEntity.tableName, remindList);
		return meetPeroidEntity;
	}

	/**
	 * 发布
	 *
	 * @description:
	 * @param dataMap
	 * @param sessionUserBean
	 * @author: donghang
	 * @date: 2020年11月4日下午11:56:44
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void publish(Map<String, Object> dataMap, SessionUserBean sessionUserBean) {
		// 如果已经发布过，则需要删除周期会议之前生成的会议
		if (ConvertUtil.convertToLong(dataMap.get(MeetManageEntity.FieldState)) == MeetStateEnum.Publish) {
			this.deleteOldFatureData(ConvertUtil.convertToString(dataMap.get("id")));
		}
		// 1.更新发布状态
		dataMap.put(MeetManageEntity.FieldState, MeetStateEnum.Publish);
		MeetPeroidTaskEntity meetPeroidTaskEntity = this.save(dataMap, sessionUserBean);
		// 得到周期的一系列会议
		PeroidParams repeatParams = this.convertPeriodParamByTaskEntity(meetPeroidTaskEntity);
		List<Map<String, Object>> list = this.peroidRepeatService.getPeroidDays(repeatParams);
		// 得到权限
		Map<String, Object> selectUsers = (Map<String, Object>) dataMap.get("selectUsers");
		List<BasePermissionManageEntity> permissionList = this.basePermissionManageService.processSelectUsers(
				selectUsers, MeetPersonTypeEnum.Attend, sessionUserBean.getUser().getCode(),
				sessionUserBean.getUser().getName());
		// 得到提醒
		List<Map<String, Object>> remindList = (List<Map<String, Object>>) dataMap.get("remindList");
		// 2.生成一系列会议
		this.generateAllDate(list, meetPeroidTaskEntity, remindList, permissionList, false);
	}

	/**
	 * 取消发布
	 *
	 * @description:
	 * @param dataMap
	 * @param sessionUserBean
	 * @author: donghang
	 * @date: 2020年11月5日上午11:54:32
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void cancel(Map<String, Object> dataMap, SessionUserBean sessionUserBean) {
		// 1.更新周期会议状态
		dataMap.put(MeetManageEntity.FieldState, MeetStateEnum.Cancel);
		this.update(dataMap);
		// 2.删除周期会议下的会议
		this.deleteOldFatureData(ConvertUtil.convertToString(dataMap.get("id")));
	}

	/**
	 * 移交周期会议给其他人
	 *
	 * @description:
	 * @author: donghang
	 * @date: 2020年11月23日上午11:22:22
	 * @modify:
	 */
	public void transfer(Map<String, Object> dataMap) {
		String id = ConvertUtil.convertToString(dataMap.get("id"));
		String usercode = ConvertUtil.convertToString(dataMap.get("usercode"));
		String username = ConvertUtil.convertToString(dataMap.get("username"));
		this.update(dataMap);
		// 将会议全部修改为当前人
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("update meetmanage set usercode='{0}',username='{1}' where peroidtaskid='{2}'", usercode,
				username, id);
		this.meetManageService.updateExecute(sql.toString());
	}

	/**
	 * 删除周期会议下所有关联的没有开始的会议
	 *
	 * @description:
	 * @param meetPeroidTaskEntity
	 * @author: donghang
	 * @date: 2020年11月10日上午11:09:24
	 * @modify:
	 */
	private void deleteOldFatureData(String peroidMeetId) {
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("1=1");
		sql.appendLineSingle(" and peroidtaskid='{0}'", peroidMeetId);
		sql.appendLineSingle(" and endtime>={0}", SQLAdapter.toDateLong(DateUtil.dateToString(new Date())));
		sql.appendLineSingle(" and state!='{0}'", MeetStateEnum.Publish);
		List<MeetManageEntity> meetList = this.meetManageService.queryByWhere(sql.toString());
		if (meetList.size() > 0) {
			String meetIds = "";
			for (MeetManageEntity meetManageEntity : meetList) {
				meetIds += meetManageEntity.getId() + ",";
			}
			meetIds = meetIds.substring(0, meetIds.length() - 1);
			// 批量删除会议
			this.meetManageService.deleteByIds(meetIds);
		}

	}

	/**
	 * 周期会议生成会议
	 *
	 * @description:
	 * @param timeList
	 * @param taskEntity
	 * @param remindList
	 * @param userList
	 * @param generateExpireData
	 * @author: donghang
	 * @date: 2020年11月5日下午11:26:32
	 * @modify:
	 */
	private void generateAllDate(List<Map<String, Object>> timeList, MeetPeroidTaskEntity meetPeroidTaskEntity,
			List<Map<String, Object>> remindList, List<BasePermissionManageEntity> userList,
			boolean generateExpireData) {
		Date nowDate = new Date();
		List<BasicEntity> meetList = new ArrayList<>();
		List<BasicEntity> remindConfigList = new ArrayList<>();
		List<BasicEntity> permissionList = new ArrayList<>();
		for (Map<String, Object> timeMap : timeList) {
			MeetManageEntity meetEntity = this.generateMeetEntity(timeMap, meetPeroidTaskEntity);
			if (!generateExpireData) {
				// 过期数据不生成
				if (meetEntity.getEndtime().compareTo(nowDate) < 0) {
					continue;
				}
			}
			meetEntity.setState(MeetStateEnum.Wait);
			// 会议生成（包括人员、提醒配置）
			meetList.add(meetEntity);
			if (userList != null) {
				for (BasePermissionManageEntity userEntity : userList) {
					BasePermissionManageEntity newEntity = JSON.parseObject(JSON.toJSONString(userEntity),
							BasePermissionManageEntity.class);
					newEntity.setId(0);
					newEntity.setSourceid(ConvertUtil.convertToString(meetEntity.getId()));
					newEntity.setSourcetype(MeetManageEntity.tableName);
					newEntity.setCreateon(new Date());
					newEntity.setModifiedon(newEntity.getCreateon());
					permissionList.add(newEntity);
				}
			}
			if (remindList != null) {
				for (Map<String, Object> item : remindList) {
					BaseRemindConfigEntity newEntity = new BaseRemindConfigEntity();
					newEntity.convertFromMap(item);
					newEntity.setId(0);
					newEntity.setSourceid(ConvertUtil.convertToString(meetEntity.getId()));
					newEntity.setSourcetype(MeetManageEntity.tableName);
					newEntity.setState(-1);
					newEntity.setCreateon(new Date());
					newEntity.setModifiedon(newEntity.getCreateon());
					remindConfigList.add(newEntity);
				}

			}
		}
		this.meetManageService.insertBatch(meetList);
		this.baseRemindConfigService.insertBatch(remindConfigList);
		this.basePermissionManageService.insertBatch(permissionList);
	}

	/**
	 * 根据时间和周期任务生成会议对象
	 *
	 * @description:
	 * @param timeMap
	 * @param meetPeroidTaskEntity
	 * @return
	 * @author: donghang
	 * @date: 2020年11月5日下午11:37:29
	 * @modify:
	 */
	private MeetManageEntity generateMeetEntity(Map<String, Object> timeMap,
			MeetPeroidTaskEntity meetPeroidTaskEntity) {
		DateBetween duration = DateBetween.create(meetPeroidTaskEntity.getBegintime(),
				meetPeroidTaskEntity.getEndtime());
		int times = ConvertUtil.convertToInt(duration.between(DateUnit.MS));
		String beginString = DateUtil.dateToString(meetPeroidTaskEntity.getBegintime(), "yyyy-MM-dd HH:mm:ss");
		Date beginTime = ConvertUtil.convertToDate(timeMap.get("date").toString() + " " + beginString.split(" ")[1]);
		Date endTime = new Date(Instant.ofEpochMilli(beginTime.getTime()).plusMillis(times).toEpochMilli());
		MeetManageEntity entity = new MeetManageEntity();
		long[] arrayId = PrimaryKeyUtil.GeneIDsFromCache(entity.getTableName(), 1);
		String docNo = String.valueOf(arrayId[0]);
		docNo = docNo.substring(0, 6) + docNo.substring(9);
		entity.setId(arrayId[0]);
		entity.setMeetnum(docNo);
		entity.setBegintime(beginTime);
		entity.setEndtime(endTime);
		entity.setContent(meetPeroidTaskEntity.getContent());
		entity.setName(meetPeroidTaskEntity.getName() + "【" + ConvertUtil.convertToString(timeMap.get("name")) + "】");
		entity.setAirlinecompany(meetPeroidTaskEntity.getAirlinecompany());
		entity.setKeywords(meetPeroidTaskEntity.getKeywords());
		entity.setLaunchorgindex(meetPeroidTaskEntity.getLaunchorgindex());
		entity.setLaunchorgname(meetPeroidTaskEntity.getLaunchorgname());
		entity.setLaunchorgtype(meetPeroidTaskEntity.getLaunchorgtype());
		entity.setLaunchusercode(meetPeroidTaskEntity.getLaunchusercode());
		entity.setLaunchusername(meetPeroidTaskEntity.getLaunchusername());
		entity.setManageusercodes(meetPeroidTaskEntity.getManageusercodes());
		entity.setManageusernames(meetPeroidTaskEntity.getManageusernames());
		entity.setMeetroomid(meetPeroidTaskEntity.getMeetroomid());
		entity.setMeetroomtype(meetPeroidTaskEntity.getMeetroomtype());
		entity.setMeetstyle(meetPeroidTaskEntity.getMeetstyle());
		entity.setMeettypeid(meetPeroidTaskEntity.getMeettypeid());
		if(StrUtil.isEmpty(entity.getAirlinecompany())){
			entity.setPlace(meetPeroidTaskEntity.getPlace());
		}
		entity.setUsercode(meetPeroidTaskEntity.getUsercode());
		entity.setUsername(meetPeroidTaskEntity.getUsername());
		entity.setPeroidtaskid(meetPeroidTaskEntity.getId());
		entity.setTelephone(meetPeroidTaskEntity.getTelephone());
		entity.setAdvancesubmittime(
				DateUtil.addDate(beginTime, -1 * meetPeroidTaskEntity.getAdvancedays(), Calendar.DATE));
		entity.setCreateon(new Date());
		return entity;
	}

	/**
	 *
	 * @description:
	 * @param taskEntity
	 * @return
	 * @author: donghang
	 * @date: 2020年11月5日下午11:21:33
	 * @modify:
	 */
	private PeroidParams convertPeriodParamByTaskEntity(MeetPeroidTaskEntity taskEntity) {
		PeroidParams repeatParams = new PeroidParams();
		repeatParams.setBeginTime(DateUtil.dateToString(taskEntity.getBegintime(), "yyyy-MM-dd"));
		repeatParams.setEndtype(taskEntity.getStoptype());
		if (taskEntity.getStoptype() == 1) {
			repeatParams.setEndTime(DateUtil.dateToString(taskEntity.getStoptime(), "yyyy-MM-dd"));
		} else {
			repeatParams.setTimes(taskEntity.getRepeatcount());
		}
		repeatParams.setDaySequence(taskEntity.getDaysequence());
		repeatParams.setMonthWeekTime(taskEntity.getWeeksequence());
		repeatParams.setPeriodFrequency(taskEntity.getPeriodfrequency());
		repeatParams.setPeriodType(taskEntity.getPeriodtype());
		repeatParams.setRepeatEveryType(taskEntity.getMonthrepeattype());
		return repeatParams;
	}

	/**
	 *
	 * @description:
	 * @param mapRow
	 * @param datacodeCache
	 * @author: donghang
	 * @date: 2020年11月9日上午9:12:16
	 * @modify:
	 */
	public void setDispFields(Map<String, Object> mapRow, DatacodeCache datacodeCache) {
		super.setDispFields(mapRow, datacodeCache);
		String temp;
		if (mapRow.get("meettypeid") != null) {
			temp = mapRow.get("meettypeid").toString();
			String name = "", parentName = "";
			List<MeetTypeManageEntity> meetList = this.meetTypeManageService.queryByWhere("id=" + temp);
			if (meetList.size() == 1) {
				name = meetList.get(0).getName();
				if (meetList.get(0).getParentid() > 0) {
					List<MeetTypeManageEntity> parentList = this.meetTypeManageService
							.queryByWhere("id=" + meetList.get(0).getParentid());
					if (parentList.size() == 1) {
						parentName = parentList.get(0).getName();
					}
				}
			}
			if (parentName.length() > 0) {
				mapRow.put("dispmeettypeid", parentName + "/" + name);
			} else {
				mapRow.put("dispmeettypeid", name);
			}
		}
	}
}
